-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parse symmetry info and show in cell tab #328
Conversation
fixes aiidalab/aiidalab-qe#244 |
@unkcpz I see there are still some non-completed tasks for this PR. Whenever this is ready please assign relevant people for the review. |
There is still one thing probably good to have. When the structure is not chosen or uploaded the |
@unkcpz Please re-request my review when this is ready, thank you! |
@csadorf Yes, it is ready to review. |
8f80b2e
to
05d0f38
Compare
@@ -153,3 +154,12 @@ class StatusHTML(_StatusWidgetMixin, ipw.HTML): | |||
@traitlets.observe("message") | |||
def _observe_message(self, change): | |||
self.show_temporary_message(change["new"]) | |||
|
|||
|
|||
def ase2spglib(ase_structure: Atoms): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you declare the return type here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
aiidalab_widgets_base/viewers.py
Outdated
@@ -167,15 +168,16 @@ class _StructureDataBaseViewer(ipw.VBox): | |||
selection = List(Int) | |||
selection_adv = Unicode() | |||
supercell = List(Int) | |||
cell = Instance(Cell, allow_none=True) | |||
cell = Instance(Cell, allow_none=True) # Will be deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Do we need to add a deprecation warning then?
- What is the motivation for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
per 1: Maybe (only if other app use this widget and directly use cell
traitslet, @yakutovicha if the apps from empa using this directly).
per 2: The motivation to replace cell
with ase_structure
is to read the symmetry information from the traitlets . From my point of view, it makes more sense to store and use full structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll wait for @yakutovicha to comment on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The structure
trait of the StructureDataViewer
child class serves the purpose of ase_structure
. You can extract all the information from it.
per 2: The motivation to replace
cell
withase_structure
is to read the symmetry information from the traitlets . From my point of view, it makes more sense to store and use full structure.
We actually thought of _StructureDataBaseViewer
as a base class that could be used also for the trajectory viewers. I would, therefore, be very careful in changing this part.
I would at least do this particular change in another PR so that we could carefully consider all the pros and cons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to mention that @danielhollas is currently preparing things for the trajectory viewer, so we might want to revisit the design of _StructureDataBaseViewer
class.
I can create a separate issue to collect the ideas. What do you think @unkcpz and @danielhollas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @yakutovicha please open an issue for trajectory.
I will revert this part in the pr. Basically I need the ase.Atom only for parse the symmetry info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at the implementation of this PR again, if I revert back, there is no essential changes left.
I think if we call this class a 'StructureData' viewer, the positions info should be included with is not in the original implementation, which makes not much sense to me.
@danielhollas Could you have a look at this implementation to see if this will conflict with your trajectory feature, if not, it is much easier to keep the base traitslet type change here.
Therefore, I'll remove the cell
traitslet if it is fine for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@unkcpz yeah, I am just looking into this, the split between _StructureDataBaseViewer
and StructureDataViewer
is a bit unclear to me. I think for your use case here it would make most sense if you moved the displayed_structure
traitlet here. Then you would have access to the ASE structure, you don't need extra ase_structure
traitlet.
The structure trait of the StructureDataViewer child class serves the purpose of ase_structure. You can extract all the information from it.
Just a correction to this, the structure trait can be either Atoms or AiiDA node, whereas displayed_structure
is guaranteed to be the ASE Atoms object. So that's why I think it would make sense to move here.
Regardless, I am fine with removing the cell traitlet. Since this is inside the private class, other things should not be using it anyway no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I am a bit confused with the design here. Can we have a short meeting to discuss it?
The catch here is the _StructureDataBaseViewer
has no positions info but I need to put the symmetry info in the cell
tab which needs to use cell + position info. We need first to clarify the variable names used for our class since 'cell' sometimes only refers to lattice but in some libraries refers to the whole structure.
(This was for last time, please igrone me 💔)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at the implementation of this PR again, if I revert back, there is no essential changes left.
Not really, I guess the purpose of this PR is to have the symmetry information displayed. This can stay.
the positions info should be included with is not in the original implementation
sorry, I don't understand this, could you maybe rephrase?
Just a correction to this, the structure trait can be either Atoms or AiiDA node, whereas
displayed_structure
is guaranteed to be the ASE Atoms object. So that's why I think it would make sense to move here.
No, it accepts both Atoms and AiiDA node, but then they get immediately converted into an ASE object:
aiidalab-widgets-base/aiidalab_widgets_base/viewers.py
Lines 737 to 738 in cabc5df
@validate("structure") | |
def _valid_structure(self, change): # pylint: disable=no-self-use |
Regardless, I am fine with removing the cell traitlet. Since this is inside the private class, other things should not be using it anyway no?
It will also stay as a public member of the derived classes, we still need to be careful about removing it.
[P.S.]
Overall, I would like to stress that generally, I agree - we might change the classes to better satisfy our needs. We might do it in a separate PR (as I was suggesting) or just bite the bullet and do everything here.
I try to be practical, that is why I suggest merging things that are clear and addressing the rest in a separate PR. If you want to do everything here - that is also fine with me. But keep in mind that it will cause some delays and long difficult-to-follow discussions.
aiidalab_widgets_base/viewers.py
Outdated
if self.cell: | ||
@observe("ase_structure") | ||
def _observe_ase_structure(self, _=None): | ||
if self.ase_structure: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@unkcpz In this logic, please take into account non-periodic systems by checking the pbc attribute of the ase object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! @danielhollas
I add a check and only parse and attach symmetry when pbc shows it is 3-D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@unkcpz it might also be nice to automatically hide the Cell tab in that case. Not sure how much work that would be so perhaps in another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably can update the tab widget but then need to bring it back when 3D structure is selected again, seems a bit tedious to make it work correctly, I'll take a look.
Or we can make the widget support the 2D and 1D with big cell set like we have for [optimade-client]?(https://optimadeclient.materialscloud.io/). From where if you search structure in MC2D database. Not sure I remember how we do that, I'll check it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if self.ase_structure: | |
if self.ase_structure and any(self.ase_structure.pbc): |
f907b3a
to
8fc6bb2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@unkcpz I left a couple comments, let me know if my suggestions make sense.
aiidalab_widgets_base/viewers.py
Outdated
@@ -167,15 +168,16 @@ class _StructureDataBaseViewer(ipw.VBox): | |||
selection = List(Int) | |||
selection_adv = Unicode() | |||
supercell = List(Int) | |||
cell = Instance(Cell, allow_none=True) | |||
cell = Instance(Cell, allow_none=True) # Will be deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@unkcpz yeah, I am just looking into this, the split between _StructureDataBaseViewer
and StructureDataViewer
is a bit unclear to me. I think for your use case here it would make most sense if you moved the displayed_structure
traitlet here. Then you would have access to the ASE structure, you don't need extra ase_structure
traitlet.
The structure trait of the StructureDataViewer child class serves the purpose of ase_structure. You can extract all the information from it.
Just a correction to this, the structure trait can be either Atoms or AiiDA node, whereas displayed_structure
is guaranteed to be the ASE Atoms object. So that's why I think it would make sense to move here.
Regardless, I am fine with removing the cell traitlet. Since this is inside the private class, other things should not be using it anyway no?
aiidalab_widgets_base/viewers.py
Outdated
if self.cell: | ||
@observe("ase_structure") | ||
def _observe_ase_structure(self, _=None): | ||
if self.ase_structure: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@unkcpz it might also be nice to automatically hide the Cell tab in that case. Not sure how much work that would be so perhaps in another PR?
aiidalab_widgets_base/viewers.py
Outdated
@@ -759,10 +796,10 @@ def _observe_structure(self, change): | |||
# Remove the current structure(s) from the viewer. | |||
if change["new"] is not None: | |||
self.set_trait("displayed_structure", change["new"].repeat(self.supercell)) | |||
self.set_trait("cell", change["new"].cell) | |||
self.set_trait("ase_structure", change["new"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this works in general case because the structure
trait can be AiiDA node (StructureData or CifData). You would need to move this to the displayed_structure
observer, but as mentioned in the other comment, I think it is easier to just move the displayed_structure
trait to the parent class.
Thanks for the review! @danielhollas |
I agree, we need to meet to clear things out. Just as a brief mention: the idea to keep the |
Sure, let's have a quick meeting. The next AiiDAlab meeting is after the Psi-k conference and I cannot attend unfortunately since I am at another conference in Rennes. Could we do a short meeting today or tomorrow afternoon? @yakutovicha to clarify my suggestion, I would move the |
I am available both today and tomorrow. @unkcpz what about you? |
I have time today 3pm-3:30pm and tomorrow after 4pm. If you can find time, let me know. Thanks! |
@unkcpz @yakutovicha I am available now but tomorrow works as well. |
@danielhollas I've just sent you the link via email. |
c05e536
to
958b10a
Compare
Hi @yakutovicha @danielhollas, I adapt the changes without touching the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@unkcpz thanks, the code looks good to me. I have some suggestions / questions, but those could be done in subsequent PR if needed.
I did not actually test this, I am leaving that to somebody with more solid state background.
@@ -335,7 +340,8 @@ def change_camera(change): | |||
|
|||
@observe("cell") | |||
def _observe_cell(self, _=None): | |||
if self.cell: | |||
# only update cell info when it is a 3D structure. | |||
if self.cell and all(self.structure.pbc): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to either completely hide the Cell tab when the structure is not periodic, or at least explicitly indicate that inside the tab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for mentioning this. Actually, I made some effort to implement that but failed. The reason is that the code either hides the tab or adds a message inside the cell tab makes more sense to put in _cell_tab
method, but in there the self.structure
trait is not being set yet.
Adding that too this PR will bring more coupling. But you are right, if it is okay with you, I'll open an issue for this and leave it to the future after we have decoupled the base structure data view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@unkcpz did you open the issue? If yes, please mention it here for the record
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just open the issue #351 for this.
@@ -335,7 +340,8 @@ def change_camera(change): | |||
|
|||
@observe("cell") | |||
def _observe_cell(self, _=None): | |||
if self.cell: | |||
# only update cell info when it is a 3D structure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why 2D structures are not supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two reasons that make this not easy to show. First, if it is a 2D structure, the spglib does not work well with fining the symmetry for 2D structure which has an different set of space group. Secondly, I have no idea what to show for the cell information, do we still show a, b, c with c set to a large value as mimicking the vacuum layer, or don't show the c and beta in the tab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for review @danielhollas .
I don't know why I can't directly reply to the comment (they are all in Pending
state), but has to reply with the review. I think it might be I have reply using the review code last time (The first comment is from last time, please ignore it).
Sorry for the mess.
aiidalab_widgets_base/viewers.py
Outdated
@@ -167,15 +168,16 @@ class _StructureDataBaseViewer(ipw.VBox): | |||
selection = List(Int) | |||
selection_adv = Unicode() | |||
supercell = List(Int) | |||
cell = Instance(Cell, allow_none=True) | |||
cell = Instance(Cell, allow_none=True) # Will be deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I am a bit confused with the design here. Can we have a short meeting to discuss it?
The catch here is the _StructureDataBaseViewer
has no positions info but I need to put the symmetry info in the cell
tab which needs to use cell + position info. We need first to clarify the variable names used for our class since 'cell' sometimes only refers to lattice but in some libraries refers to the whole structure.
(This was for last time, please igrone me 💔)
@@ -335,7 +340,8 @@ def change_camera(change): | |||
|
|||
@observe("cell") | |||
def _observe_cell(self, _=None): | |||
if self.cell: | |||
# only update cell info when it is a 3D structure. | |||
if self.cell and all(self.structure.pbc): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for mentioning this. Actually, I made some effort to implement that but failed. The reason is that the code either hides the tab or adds a message inside the cell tab makes more sense to put in _cell_tab
method, but in there the self.structure
trait is not being set yet.
Adding that too this PR will bring more coupling. But you are right, if it is okay with you, I'll open an issue for this and leave it to the future after we have decoupled the base structure data view.
@@ -335,7 +340,8 @@ def change_camera(change): | |||
|
|||
@observe("cell") | |||
def _observe_cell(self, _=None): | |||
if self.cell: | |||
# only update cell info when it is a 3D structure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two reasons that make this not easy to show. First, if it is a 2D structure, the spglib does not work well with fining the symmetry for 2D structure which has an different set of space group. Secondly, I have no idea what to show for the cell information, do we still show a, b, c with c set to a large value as mimicking the vacuum layer, or don't show the c and beta in the tab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good also from my side, thanks @unkcpz!
for more information, see https://pre-commit.ci
3199fc2
02a864f
to
3199fc2
Compare
6d13de7
to
821fcdc
Compare
for more information, see https://pre-commit.ci
Okay, a bit late than the PR of @danielhollas (3 min 🥺), introduce a conflict here. I resolve the conflict and rebase it and should be fine now. Nothing is charged so I'll merge it without your approval. |
Move the cell tab to frontCan be set when create widget.spglib
Usingase.Atom
instead ofase.Cell
inStructureDataViewer
as active traitslet talk to other widget.dropase.Cell
for structure viewer, use onlyase.Atoms
as trait.